package com.mxx.tomcat.verification;

import com.fasterxml.jackson.databind.JavaType;
import com.mxx.common.conv.JacksonConverter;
import com.mxx.tomcat.ResponseWriter;
import com.mxx.tomcat.verification.annotation.Verify;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.context.request.NativeWebRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

/**
 * @Auther: Mr. Zeng
 * @Date: 2021/4/8 19:29
 * @Description: 暂无描述
 */
public abstract class AbstractJsonValidateArgumentResolver extends AbstractValidateArgumentResolver {
    protected final String JSON = "Json";

    public AbstractJsonValidateArgumentResolver(List<HttpMessageConverter<?>> converters, JacksonConverter jacksonConverter, ResponseWriter responseWriter) {
        super(converters, jacksonConverter, responseWriter);
    }


    public Map<String, String> getRequestParameterMap(NativeWebRequest nativeWebRequest, MethodParameter methodParameter, Verify.Type type) throws IOException, HttpMediaTypeNotSupportedException {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        String storageKey = String.format("%s_Map", type);
        Map<String, String> requestParameter = (Map<String, String>) request.getAttribute(storageKey);
        if (requestParameter == null) {
            HashMap hashMap = (HashMap) this.readWithMessageConverters(nativeWebRequest, methodParameter, HashMap.class);
            if (hashMap == null) {
                return new HashMap<>();
            }
            JavaType javaType = jacksonConverter.getJavaType(String.class);
            JavaType mapType = jacksonConverter.getMapType(HashMap.class, javaType, javaType);

            for (Map.Entry entry : (Set<Map.Entry>) hashMap.entrySet()) {
                entry.setValue(jacksonConverter.writeValueAsString(entry.getValue()));
            }
            String jsonStr = jacksonConverter.writeValueAsString(hashMap);


            requestParameter = jacksonConverter.readValue(jsonStr, mapType);
            request.setAttribute(storageKey, requestParameter);
        }
        return requestParameter;
    }

}
